package com.hrd.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hrd.common.util.HmacSha256Util;
import com.hrd.common.util.RestTemplateUtil;
import com.hrd.common.util.bean.ServiceResult;
import com.hrd.common.util.cache.RedisPoolUtil;
import com.hrd.common.util.http.HttpDeal;
import com.hrd.common.util.http.HttpUtil;
import com.hrd.common.util.properties.PropertyUtil;
import com.hrd.mybatis.bean.ext.InvModel;
import com.hrd.mybatis.bean.ext.JDResult;
import com.hrd.mybatis.bean.ext.SalOutBound;
import com.hrd.service.CommonService;
import com.smecloud.apigw.client.ApigwClient;
import com.smecloud.apigw.constant.HttpMethod;
import com.smecloud.apigw.model.ApiRequest;
import com.smecloud.apigw.model.ApiResult;
import com.smecloud.apigw.model.ApigwConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.security.SecureRandom;
import java.util.*;

/**
 * @Author: wangpeng
 * @Date: 2021/11/1 09:59
 * @Description:
 */
@Slf4j
@Service
public class CommonServiceImpl extends BaseServiceImpl implements CommonService {
    private String clientID = PropertyUtil.getSystemResourcesPropertieValue("jd.client.id");
    private String clientSecret = PropertyUtil.getSystemResourcesPropertieValue("jd.client.secret");
    private String username = PropertyUtil.getSystemResourcesPropertieValue("jd.username");
    private String password = PropertyUtil.getSystemResourcesPropertieValue("jd.password");

    private String appKey = PropertyUtil.getSystemResourcesPropertieValue("jd.appKey");
    private String appSecret = PropertyUtil.getSystemResourcesPropertieValue("jd.appSecret");
    private String outerInstanceId = PropertyUtil.getSystemResourcesPropertieValue("jd.outerInstanceId");

    private String accessTokenUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.access.token.url");
    private String accountGroupUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.account.group.url");
    private String salOutboundListUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.salOutbound.list.url");
    private String salOutboundDetailUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.salOutbound.detail.url");
    private String invListUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.invlist.url");
    private String basedataUrl = PropertyUtil.getSystemResourcesPropertieValue("kingdee.basedata.url");
    private String pushAppAuthorize = PropertyUtil.getSystemResourcesPropertieValue("kingdee.pushAppAuthorize.url");

    private final Random rand = new SecureRandom();
    private static final String[] DEFAULT_SIGNHEADERS = new String[]{"X-Api-Nonce", "X-Api-TimeStamp"};

    @Override
    public ServiceResult<String> getAccessToken() {
        ServiceResult<String> result = new ServiceResult<>();
        String accessToken = RedisPoolUtil.get("HRD_ACCESS_TOKEN_KEY");
        log.info("redis中token = {}",accessToken);

        if (StringUtils.isBlank(accessToken)) {

            try {
                JDResult jsonObject = authToken();
                log.info("认证结果：{}",JSONObject.toJSONString(jsonObject));
                String appKey = jsonObject.getAppKey();
                String appSecret = jsonObject.getAppSecret();

                Map<String, String> map = new HashMap<>();
                map.put("app_key", appKey);
                //加密app_signature
                String appSignature = HmacSha256Util.hmacSha256Base64(appKey, appSecret);
                map.put("app_signature", appSignature);
                String path = accessTokenUrl;
                ApiResult send = send(clientID, clientSecret, map, path, HttpMethod.GET);

                log.info("获取accessToken返回结果:" + send.getBody());
                if (StringUtils.isNotEmpty(send.getBody())) {
                    JSONObject resultJson = JSONObject.parseObject(send.getBody());

                    Integer errcode = resultJson.getInteger("errcode");
                    String description = resultJson.getString("description");
                    //获取成功 将token保存到Redis
                    if (0 == errcode) {
                        JSONObject data = (JSONObject) resultJson.get("data");
                        accessToken = data.getString("access_token");
                        //有效期五天
                        RedisPoolUtil.setEx("HRD_ACCESS_TOKEN_KEY", accessToken, 432000);
                        result.setSuccess(true);
                        result.setResult(accessToken);
                    } else {
                        result.setSuccess(false);
                        result.setMessage(description);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取accessToken失败");
                }
            } catch (Exception e) {
                log.error("exception:", e);
                result.setSuccess(false);
                result.setMessage("获取AccountGroup出现异常");
            }
        } else {
            result.setSuccess(true);
            result.setResult(accessToken);
        }

        return result;
    }

    public ApiResult send(String clientID, String clientSecret, Map<String, String> param, String path, HttpMethod method) {
        ApigwConfig config = new ApigwConfig();
        //设置client_id
        config.setClientID(clientID);
        //设置client_secret
        config.setClientSecret(clientSecret);
        ApigwClient apigwClient = ApigwClient.getInstance();
        //初始化API网关客户端
        apigwClient.init(config);
        ApiRequest request = new ApiRequest(method, "api.kingdee.com", path);
        request.setQuerys(param);
        request.setBodyJson(JSONObject.toJSONString("").getBytes());
        ApiResult result = apigwClient.send(request);
        return result;
    }

    /**
     * 主动授权
     */
    public JDResult authToken() {

        JDResult dataModel = new JDResult();
        Map<String, String> map = new HashMap<>();
        map.put("outerInstanceId", outerInstanceId);
        String path = pushAppAuthorize;
        ApiResult send = send(clientID, clientSecret, map, path, HttpMethod.POST_BODY);
        log.info("主动授权返回结果：{}", send.getBody());

        if (send != null) {
            String body = send.getBody();
            if (StringUtils.isNotBlank(body)) {
                JSONObject jsonObject = JSONObject.parseObject(body);
                if (jsonObject.get("data") != null && jsonObject.getJSONArray("data").size() != 0) {
                    JSONArray data = jsonObject.getJSONArray("data");
                    dataModel = JSONObject.parseObject(JSONObject.toJSONString(data.get(0)), JDResult.class);
                    //有效期五天
                    RedisPoolUtil.setEx("HRD_AUTH_KEY", JSONObject.toJSONString(dataModel), 432000);
                }
            }
        }
        return dataModel;
    }


    public ServiceResult<JSONObject> getAccountGroup(String accessToken) {

        ServiceResult<JSONObject> result = new ServiceResult<>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupName","ns-fork1");
        jsonObject.put("accountId","1628049357869235534");
        result.setSuccess(true);
        result.setResult(jsonObject);

//        String accountGroupStr = RedisPoolUtil.get("HRD_ACCOUNT_GROUP_KEY");
//        //从redis中获取账套信息
//        if (StringUtils.isNotBlank(accountGroupStr)) {
//            JSONObject accountGroup = JSONObject.parseObject(accountGroupStr, JSONObject.class);
//            result.setSuccess(true);
//            result.setResult(accountGroup);
//            return result;
//        }
//
//        //根据toke获取用户账套信息
//        Map<String, String> headerMap = new HashMap<>();
//        headerMap.put("content-type", "application/json");
//
//        try {
//            String accountResult = HttpUtil.post(accountGroupUrl + "?access_token=" + accessToken, headerMap, null, null);
//
//            log.info("用户账套信息返回结果：" + accountResult);
//            if (StringUtils.isNotEmpty(accountResult)) {
//                JSONObject accountResultJson = JSONObject.parseObject(accountResult);
//                boolean success = accountResultJson.getBoolean("success");
//                String message = accountResultJson.getString("message");
//
//                //将用户账套信息保存到Redis
//                if (success) {
//                    List<JSONObject> dataArray = (List<JSONObject>) accountResultJson.get("data");
//                    JSONObject accountData = dataArray.get(0);
//                    List<JSONObject> accountGroups = (List<JSONObject>) accountData.get("accountGroups");
//                    //TODO 上线修改
//                    JSONObject accountGroup = accountGroups.get(0);
//                    for (JSONObject group : accountGroups) {
//                        if (group.getString("accountName").indexOf("锐德工程机械有限公司")!=-1){
//                            accountGroup = group;
//                        }
//                    }
//                    RedisPoolUtil.setEx("HRD_ACCOUNT_GROUP_KEY", JSONObject.toJSONString(accountGroup), 432000);
//                    result.setSuccess(true);
//                    result.setResult(accountGroup);
//                } else {
//                    result.setSuccess(false);
//                    result.setMessage(message);
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            result.setSuccess(false);
//            result.setMessage("获取AccountGroup出现异常");
//        }
        return result;
    }

    @Override
    public ServiceResult<List<JSONObject>> getSalOutboundList(SalOutBound record, String accessToken) {

        ServiceResult<List<JSONObject>> result = new ServiceResult<>();
        //获取token
        if (StringUtils.isNotBlank(accessToken)) {
            Map<String, String> salOutListHeaderMap = getHeaderMap();
            //设置参数
            JSONObject param = new JSONObject();
            HttpEntity entity = new StringEntity(param.toJSONString(), "UTF-8");
            try {
                String httpResult = HttpUtil.post(salOutboundListUrl + "?access_token=" + accessToken, salOutListHeaderMap, null, entity);

                log.info("出库单列表返回结果：{}", httpResult);
                if (StringUtils.isNotEmpty(httpResult)) {
                    JSONObject resultJson = JSONObject.parseObject(httpResult);
                    boolean success = resultJson.getBoolean("success");
                    String message = resultJson.getString("message");
                    //将用户账套信息保存到Redis
                    if (success) {
                        JSONObject data = resultJson.getJSONObject("data");
                        List<JSONObject> resultList = (List<JSONObject>) data.get("rows");
                        result.setSuccess(true);
                        result.setResult(resultList);
                    } else {
                        result.setSuccess(false);
                        result.setMessage(message);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取出库单列表失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setMessage("获取出库单列表异常");
            }
        } else {
            result.setMessage("accessToken失效");
            result.setSuccess(false);
        }
        return result;
    }

    @Override
    public ServiceResult<JSONObject> getSalOutboundDetail(String id, String accessToken) {
        //TODO 取价税合计做计算

        ServiceResult<JSONObject> result = new ServiceResult<>();
        //获取token
        if (StringUtils.isNotBlank(accessToken)) {
            Map<String, String> salOutListHeaderMap = getHeaderMap();
            //设置参数
            JSONObject param = new JSONObject();
            param.put("id", id);
            HttpEntity entity = new StringEntity(param.toJSONString(), "UTF-8");
            try {
                String httpResult = HttpUtil.post(salOutboundDetailUrl + "?access_token=" + accessToken, salOutListHeaderMap, null, entity);

                log.info("出库单详情返回结果：{}", httpResult);
                if (StringUtils.isNotEmpty(httpResult)) {
                    JSONObject resultJson = JSONObject.parseObject(httpResult);
                    boolean success = resultJson.getBoolean("success");
                    String message = resultJson.getString("message");

                    if (success) {
                        JSONObject data = resultJson.getJSONObject("data");
                        result.setSuccess(true);
                        result.setResult(data);
                    } else {
                        result.setSuccess(false);
                        result.setMessage(message);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取出库单详情失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setMessage("获取出库单详情异常");
            }
        } else {
            result.setMessage("accessToken失效");
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 获取请求头
     *
     * @param
     * @return
     */
    public Map<String, String> getHeaderMap() {
        Map<String, String> headerMap = new HashMap<>();
        JDResult jdResult = authToken();

        //设置请求头使用add方法
        headerMap.put("Content-Type", "application/json;charset=UTF-8");
        headerMap.put("groupName", jdResult.getGroupName());
        headerMap.put("accountId", jdResult.getAccountId());
        headerMap.put("X-GW-Router-Addr", jdResult.getDomain());
        return headerMap;
    }

    @Override
    public ServiceResult<List<InvModel>> getIvnList(String date, String accessToken) {

        ServiceResult<List<InvModel>> result = new ServiceResult<>();
        //获取token
        if (StringUtils.isNotBlank(accessToken)) {
            Map<String, String> salOutListHeaderMap = getHeaderMap();
            //设置参数
            JSONObject param = new JSONObject();
            if (StringUtils.isNotBlank(date)) {
                param.put("pointdate", date);
            }
            HttpEntity entity = new StringEntity(param.toJSONString(), "UTF-8");
            try {
                String httpResult = HttpUtil.post(invListUrl + "?access_token=" + accessToken, salOutListHeaderMap, null, entity);

                log.info("库存列表返回结果：{}", httpResult);
                if (StringUtils.isNotEmpty(httpResult)) {
                    JSONObject resultJson = JSONObject.parseObject(httpResult);
                    boolean success = resultJson.getBoolean("success");
                    String message = resultJson.getString("message");

                    if (success) {
                        JSONObject data = resultJson.getJSONObject("data");
                        if (data != null && data.get("rows") != null) {
                            List<InvModel> list = JSONArray.parseArray(data.getString("rows"), InvModel.class);
                            result.setResult(list);
                        } else {
                            result.setResult(new ArrayList<>());
                        }
                        result.setSuccess(true);

                    } else {
                        result.setSuccess(false);
                        result.setMessage(message);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取库存列表失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setMessage("获取出库存列表异常");
            }
        } else {
            result.setMessage("accessToken失效");
            result.setSuccess(false);
        }
        return result;
    }

    @Override
    public ServiceResult<JSONArray> getBaseData( String accessToken) {

        ServiceResult<JSONArray> result = new ServiceResult<>();
        //获取token
        if (StringUtils.isNotBlank(accessToken)) {
            Map<String, String> salOutListHeaderMap = getHeaderMap();
            //设置参数
            JSONObject param = new JSONObject();
            param.put("pagesize","100");
            HttpEntity entity = new StringEntity(param.toJSONString(), "UTF-8");
            try {
                String httpResult = HttpUtil.post(basedataUrl + "?access_token=" + accessToken, salOutListHeaderMap, null, entity);

                log.info("仓库列表返回结果：{}", httpResult);
                if (StringUtils.isNotEmpty(httpResult)) {
                    JSONObject resultJson = JSONObject.parseObject(httpResult);
                    boolean success = resultJson.getBoolean("success");
                    String message = resultJson.getString("message");

                    if (success) {
                        JSONArray data = resultJson.getJSONObject("data").getJSONArray("rows");
                        result.setSuccess(true);
                        result.setResult(data);
                    } else {
                        result.setSuccess(false);
                        result.setMessage(message);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取仓库列表失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setMessage("获取仓库列表异常");
            }
        } else {
            result.setMessage("accessToken失效");
            result.setSuccess(false);
        }
        return result;
    }

    @Override
    public ServiceResult<JSONArray> getSpaceData(String accessToken,String groupid) {

        ServiceResult<JSONArray> result = new ServiceResult<>();
        //获取token
        if (StringUtils.isNotBlank(accessToken)) {
            Map<String, String> salOutListHeaderMap = getHeaderMap();
            //设置参数
            JSONObject param = new JSONObject();
            param.put("pagesize","100");
            param.put("groupid",new String[]{groupid});
            HttpEntity entity = new StringEntity(param.toJSONString(), "UTF-8");
            try {
                String httpResult = HttpUtil.post( "http://api.kingdee.com/jdy/basedata/space_list?access_token=" + accessToken, salOutListHeaderMap, null, entity);

                log.info("库位列表返回结果：{}", httpResult);
                if (StringUtils.isNotEmpty(httpResult)) {
                    JSONObject resultJson = JSONObject.parseObject(httpResult);
                    boolean success = resultJson.getBoolean("success");
                    String message = resultJson.getString("message");

                    if (success) {
                        JSONArray data = resultJson.getJSONObject("data").getJSONArray("rows");
                        result.setSuccess(true);
                        result.setResult(data);
                    } else {
                        result.setSuccess(false);
                        result.setMessage(message);
                    }
                } else {
                    result.setSuccess(false);
                    result.setMessage("获取库位列表失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setMessage("获取仓库列表异常");
            }
        } else {
            result.setMessage("accessToken失效");
            result.setSuccess(false);
        }
        return result;
    }

}
